package util;

import java.net.URL;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Properties;
import java.util.TimeZone;

import models.MensagemMT;
import models.SiteConfig;
import play.mvc.Router;

import com.google.appengine.api.mail.MailService;
import com.google.appengine.api.mail.MailServiceFactory;
import com.google.appengine.api.urlfetch.HTTPHeader;
import com.google.appengine.api.urlfetch.HTTPMethod;
import com.google.appengine.api.urlfetch.HTTPRequest;
import com.google.appengine.api.urlfetch.HTTPResponse;
import com.google.appengine.api.urlfetch.URLFetchService;
import com.google.appengine.api.urlfetch.URLFetchServiceFactory;

import controllers.SMSNotifier;

/**
 * Interface para o Broker SMS
 * 
 * @author Aldrin Leal
 * 
 */
public class SMSUtil {
	protected String url;

	protected String userId;

	protected String password;

	protected String destination;

	protected String text;

	protected String originator;

	SMSUtil() {
		loadConfig();
	}

	protected void loadConfig() {
		SiteConfig siteConfig = null;

		siteConfig = SiteConfig.load();

		Properties properties = siteConfig.getProperties();

		this.url = properties.getProperty("sms.broker.url");
		this.userId = properties.getProperty("sms.broker.userKey");
		this.password = properties.getProperty("sms.broker.password");
		this.originator = properties.getProperty("sms.broker.originator");
	}

	public SMSUtil setDestination(String destination) {
		this.destination = destination;
		return this;
	}

	public SMSUtil setOriginator(String originator) {
		this.originator = originator;
		return this;
	}

	public SMSUtil setText(String text) {
		this.text = text;
		return this;
	}

	public HTTPResponse send() throws Exception {
		String payload = getPayload();

		URLFetchService urlFetchService = URLFetchServiceFactory
				.getURLFetchService();

		HTTPRequest httpRequest = new HTTPRequest(new URL(url), HTTPMethod.POST);
		httpRequest.setHeader(new HTTPHeader("Content-Type", "text/xml"));

		httpRequest.setPayload(payload.getBytes("ISO8859-1"));

		httpRequest.getFetchOptions().setDeadline(60000.0);

		HTTPResponse httpResult = urlFetchService.fetch(httpRequest);

		return httpResult;
	}

	protected String getPayload() {
		MensagemMT mensagemMT = new MensagemMT();

		mensagemMT.setContent(text);
		mensagemMT.setDestination(destination);

		mensagemMT.insert();

		String sourceXml = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>"
				+ "<aspsms>"
				+ String.format("<Userkey>%s</Userkey>", userId)
				+ String.format("<Password>%s</Password>", password)
				+ String.format("<Originator>%s</Originator>", originator)
				+ "<Recipient>"
				+ String.format("<PhoneNumber>%s</PhoneNumber>", destination)
				+ String.format("<TransRefNumber>%d</TransRefNumber>",
						mensagemMT.getOid())
				+ "</Recipient>"
				+ String.format("<MessageData>%s</MessageData>", text)
				+ "<LifeTime>5</LifeTime>"
				+ "<TimeZone>GMT</TimeZone>"
				+ "<DeferredDeliveryTime>"
				+ getDeferredDeliveryTime()
				+ "</DeferredDeliveryTime>"
				+ "<TimeOut>5</TimeOut>"
				+ "<Action>SendTextSMS</Action>"
				+ "<URLBufferedMessageNotification>"
				+ Router.getFullUrl(SMSNotifier.class.getName() + ".buffered")
				+ "?id="
				+ "</URLBufferedMessageNotification>"
				+ "<URLDeliveryNotification>"
				+ Router.getFullUrl(SMSNotifier.class.getName() + ".delivered")
				+ "?id="
				+ "</URLDeliveryNotification>"
				+ "<URLNonDeliveryNotification>"
				+ Router.getFullUrl(SMSNotifier.class.getName()
						+ ".notDelivered")
				+ "?id="
				+ "</URLNonDeliveryNotification>" + "</aspsms>";

		return sourceXml;
	}

	private String getDeferredDeliveryTime() {
		Calendar calendar = Calendar.getInstance();

		calendar.add(Calendar.MINUTE, 2);

		Date dateTime = calendar.getTime();

		DateFormat dateFormat = new SimpleDateFormat("ddMMyyyyHHmmss");

		TimeZone utcTimeZone = TimeZone.getTimeZone("GMT");

		dateFormat.setTimeZone(utcTimeZone);

		String result = dateFormat.format(dateTime);

		return result;
	}

	public static SMSUtil create() throws Exception {
		return new SMSUtil();
	}

	public static SMSUtil create(Class<?> smsUtilClass) {
		SMSUtil instance = null;

		if (smsUtilClass.equals(SMSUtil.class)) {
			instance = new SMSUtil();
		} else if (smsUtilClass.equals(HumanSMSUtil.class)) {
			instance = new HumanSMSUtil();
		} else {
			throw new IllegalArgumentException("Invalid SMSUtil ref");
		}

		instance.loadConfig();

		return instance;
	}

	public void sendAsMail() throws Exception {
		MailService mailService = MailServiceFactory.getMailService();
		MailService.Message message = new MailService.Message();
		String payload = getPayload();

		message.setSender("aldrinleal@gmail.com");
		message.setCc("aldrin@leal.eng.br");
		message.setReplyTo("xml-reply@mobitransitobel.appspotmail.com");
		message.setTo("xml@smtp.aspsms.com");
		message.setSubject("SMS Message");
		message.setTextBody(payload);

		mailService.send(message);
	}
}
